/**
 * @author Vitor Franco do Carmo (vitor.carmo@cpmbraxis.com)
 * @since 03/08/2013
 *
 */
package br.com.vfcfw.test;

import junit.framework.TestCase;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

import br.com.vfcfw.test.functional.browser.ChromeNavegador;
import br.com.vfcfw.test.functional.browser.FirefoxNavegador;
import br.com.vfcfw.test.functional.browser.HtmlUnitNavegador;
import br.com.vfcfw.test.functional.browser.INavegador;
import br.com.vfcfw.test.functional.browser.InternetExplorerNavegador;
import br.com.vfcfw.test.functional.enums.TipoNavegador;


/**
 * Classe base para os testes funcionais.
 * 
 * @author Vitor Franco do Carmo (vitor.carmo@cpmbraxis.com)
 * @since 03/08/2013
 * 
 */
@RunWith(BlockJUnit4ClassRunner.class)
public abstract class BaseTesteFuncional extends TestCase {

    private static INavegador navegadorTesteFuncional;

    protected static WebDriver driver;

    protected static Wait<WebDriver> wait;

    private static String paginaInicial;

    private static Integer esperar;

    /**
     * Construtor da classe.
     */
    public BaseTesteFuncional(TipoNavegador tipoNavegador, String paginaInicial, Integer esperar) {

        super();
        inicializarNavegador(tipoNavegador, paginaInicial, esperar);
    }

    /**
     * Inicializa os objetos antes da execução da classe de teste funcional.
     */
    public static void inicializarServico() {

        navegadorTesteFuncional.inicializarServico();
    }

    /**
     * Finaliza os objetos depois da execução da classe de teste funcional.
     */
    @AfterClass
    public static void finalizarServico() {

        navegadorTesteFuncional.finalizarServico();
    }

    /**
     * Inicializa os objetos antes da execução de cada teste funcional.
     */
    @Before
    public void inicializarTeste() {

        navegadorTesteFuncional.inicializarTeste();

        driver = navegadorTesteFuncional.obterDriver();

        if (esperar != null) {

            wait = new WebDriverWait(driver, esperar);
        }
        driver.get(paginaInicial);
    }

    /**
     * Finaliza os objetos depois da execução de cada teste funcional.
     */
    @After
    public void finalizarTeste() {

        navegadorTesteFuncional.finalizarTeste();
    }

    /**
     * Inicializa o navegador na página inicial.
     * 
     * @param tipoNavegador {@link TipoNavegador} Tipo do navegador que será inicializado.
     * @param paginaInicial Página inicial que será aberta ao iniciar o navegador.
     * @param esperar Tempo (segundos) que o navegador vai esperar para abrir a página sem dar erro.
     */
    public static void inicializarNavegador(TipoNavegador tipoNavegador, String paginaInicial, Integer esperar) {

        switch (tipoNavegador) {
            case CHROME:
                navegadorTesteFuncional = new ChromeNavegador();
                break;
            case FIREFOX:
                navegadorTesteFuncional = new FirefoxNavegador();
                break;
            case INTERNET_EXPLORER:
                navegadorTesteFuncional = new InternetExplorerNavegador();
                break;
            case HTML_UNIT:
                navegadorTesteFuncional = new HtmlUnitNavegador();
                break;

            default:
                break;
        }

        BaseTesteFuncional.paginaInicial = paginaInicial;
        BaseTesteFuncional.esperar = esperar;

        inicializarServico();
    }

    /**
     * Retorna o {@link WebDriver} atual.
     * 
     * @return {@link WebDriver}.
     */
    public static WebDriver obterDriverAtual() {

        return driver;
    }

}
